<template>
  <div class="workflow">
    <div class="toolbar" ref="toolbar">
      <ul class="diagram-samples">
        <li class="diagram-sample--item">
          <div class="diagram-sample--shape diagram-sample--shape-process"></div>
          <div class="diagram-shape--text">处理流程</div>
        </li>
        <li class="diagram-sample--item">
          <div class="diagram-sample--shape diagram-sample--shape-condition"></div>
          <div class="diagram-shape--text">条件判断</div>
        </li>
        <li class="diagram-sample--item">
          <div class="diagram-sample--shape diagram-sample--shape-line"></div>
          <div class="diagram-shape--text">连接线</div>
        </li>
      </ul>
    </div>
    <div class="canvas" ref="canvas"></div>
    <!--    <contextmenu ref="menu"/>-->
  </div>
</template>

<script>
import {dia, layout, shapes} from 'jointjs'
import dagre from 'dagre'
import graphlib from '@dagrejs/graphlib'
import data from "./data";
import Contextmenu from "./Contextmenu";

export default {
  // eslint-disable-next-line vue/no-unused-components
  components: {Contextmenu},
  data() {
    return {
      graph: null,
      paper: null,
      items: data,
      nodeSet: {}
    }
  },
  mounted() {
    this.init()
    this.render()
  },
  methods: {
    init() {
      const canvasRect = this.$refs.canvas.getClientRects()[0]
      this.graph = new dia.Graph()
      this.paper = new dia.Paper({
        el: this.$refs.canvas,
        model: this.graph,
        width: canvasRect.width,
        height: canvasRect.height,
        gridSize: 1
      })
      // See https://resources.jointjs.com/docs/jointjs/v3.3/joint.html#dia.Paper.events
      // this.paper.on('cell:pointerclick', (cell, e, x, y) => {
      //   console.log(cell, e, x, y)
      // })
      // this.paper.on('element:contextmenu', (element, e, x, y) => {
      //   this.$refs.menu.show('element', e, x, y, element)
      // })
      // this.paper.on('link:contextmenu', (link, e, x, y) => {
      //   this.$refs.menu.show('link', e, x, y, link)
      // })
      // this.paper.on('blank:contextmenu', (e, x, y) => {
      //   this.$refs.menu.show('blank', e, x, y)
      // })
      this.paper.on('element:pointerclick', (cell) => {
        // 根据 cell.model.attributes.type 判断是事件，结束和中间节点 standard.Ellipse standard.Rectangle
        console.log(cell) // nodeSet 遍历item.id === 点击当前元素 中 cell.model.id
        Object.keys(this.nodeSet).forEach(item => {
          if (this.nodeSet[item].id === cell.model.id) {
            console.log(item) // 当前点击元素id
            console.log(data[item]) // 当前点击元素内容
          }
        })
      })
    },
    render() {
      const {nodes, links, nodeSet} = this

      nodes.forEach((node, i) => {
        const option = {
          position: {
            x: 60 + (100 + 50) * i,
            y: 60
          },
          size: {
            width: 100,
            height: 40
          },
          attrs: {
            body: {
              fill: '#ddd',
              strokeWidth: 1,
              stroke: '#ccc'
            },
            label: {
              text: node.name,
              fill: '#333'
            }
          }
        }
        let item
        if (node.type === 'start' || node.type === 'end') {
          item = new shapes.standard.Ellipse(option)
        } else {
          item = new shapes.standard.Rectangle(option)
        }
        item.addTo(this.graph)

        nodeSet[node.id] = item
      })

      links.forEach(([from, to]) => {
        const link = new shapes.standard.Link({
          source: nodeSet[from],
          target: nodeSet[to],
          attrs: {
            line: {
              stroke: '#aaa'
            }
          }
        })
        link.addTo(this.graph)
      })
      this.doLayout()
    },
    doLayout() {
      // https://www.cnblogs.com/fyjz/p/14303003.html
      layout.DirectedGraph.layout(this.graph, {
        dagre: dagre,
        graphlib: graphlib,
        setLinkVertices: false,
        rankDir: 'LR', //节点方向 有几个选项 "TB" (top-to-bottom) / "BT" (bottom-to-top) / "LR" (left-to-right) / "RL" (right-to-left)
        align: 'DL',
        //  network-simplex tight-tree longest-path
        // 这个属性不起作用
        // ranker: 'tight-tree',
        rankSep: 50,
        marginX: 60,
        marginY: 60,
        nodeSep: 50,
        edgeSep: 20
      })
    },
    onCanvasContextmenu(e) {
      e.preventDefault()
      // if (this.contextmenu.visible) {
      //   return
      // }
      e.stopPropagation()
      return false
    }
  },
  computed: {
    nodes() {
      const nodes = []

      this.items.forEach(item => {
        nodes.push(item)
      })

      return nodes
    },
    links() {
      const links = []

      this.items.forEach(item => {
        item.next.forEach(p => {
          links.push([item.id, p])
        })
      })

      return links
    }
  }
}
</script>

<style scoped>
.workflow {
  margin: 0 auto;
  width: 100%;
  height: 100%;
  /*background-color: #aaaaaa;*/
  display: grid;
  grid-template-columns: 100px auto;
  position: relative;
}

.toolbar {
  width: 100%;
  height: 100%;
  border-right: 1px solid #dadcdf;
  box-sizing: border-box;
  z-index: 2;
}

.canvas {
  width: 100%;
  height: 100%;
  z-index: 1;
}
</style>
<style lang="less">
html, body, #app {
  height: 100%;
}

.workflow {
  .joint-cell {
    cursor: pointer;

    &:hover {
      [joint-selector="body"] {
        stroke: #666;
      }
    }

    &:active, &:focus {
      text {
        fill: #00f;
      }
      .v-line {
        color: #00f;
      }
    }
  }
}
</style>
